/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.socket.processor;

import cn.hutool.core.util.ReflectUtil;
import info.peigen.hotpot.component.gateway.socket.queue.SocketSessionQueue;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.transport.AioSession;
import org.smartboot.socket.transport.WriteBuffer;

import java.io.IOException;

/**
 * <b>(SocketServerProcessor)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/8/20
 */
@Component("socketServerProcessor")
@Slf4j
public class SocketServerProcessor<T> implements MessageProcessor<T> {
    @Inject
    SocketSessionQueue socketSessionQueue;

    @Override
    public void process(AioSession session, Object obj) {
        WriteBuffer outputStream = session.writeBuffer();
        try {
            byte[] bytes = (byte[]) ReflectUtil.getFieldValue(obj, "response");
            outputStream.writeInt(bytes.length);
            outputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void stateEvent(AioSession session, StateMachineEnum stateMachineEnum, Throwable throwable) {
        String sessionId = session.getSessionID();
        switch (stateMachineEnum) {
            case NEW_SESSION:
                log.info("有客户端连接:" + sessionId);
                socketSessionQueue.add(session);
                break;
            case INPUT_SHUTDOWN:
            case PROCESS_EXCEPTION:
            case DECODE_EXCEPTION:
            case INPUT_EXCEPTION:
            case OUTPUT_EXCEPTION:
            case SESSION_CLOSING:
            case REJECT_ACCEPT:
            case ACCEPT_EXCEPTION:
                break;
            case SESSION_CLOSED:
                log.info("有客户端关闭连接:" + sessionId);
                socketSessionQueue.remove(session);
                break;
            default:
                log.info("类型不存在");
        }
    }
}